package com.util;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Random;

/**
 * 加密工具类
 * @vesion 1.0
 */
public class EncrypterUtils {
	/** 指定加密算法为DESede */    
	private static String ALGORITHM = "DESede";     
	/** 指定密钥存放文件 */    
	private static String KEYFile = "KeyFile";  


	/**
	 * base64加密
	 * @param data
	 * @return
	 */
	public static String Base64Encode(String data){
		return new BASE64Encoder().encode(data.getBytes());
	}
	/**
	 * base64加密
	 * @param data
	 * @return
	 */
	public static String Base64Encode(String data,String encoding)throws UnsupportedEncodingException {
		return new BASE64Encoder().encode(data.getBytes(encoding));
	}
	/**
	 * base64解密
	 * @param data
	 * @return
	 */
	public static String Base64Decode(String data){
		byte[] s = null;
		try {
			s = new BASE64Decoder().decodeBuffer(data);
		} catch (IOException e) {
			s = null;
		}
		return new String(s);
	}
	
	/**
	 * base64解密
	 * @param data
	 * @return
	 */
	public static String Base64Decode(String data,String encoding) {
		if (data == null)
			return null;
		BASE64Decoder decoder = new BASE64Decoder();
		try {
			byte[] b = decoder.decodeBuffer(data);
			return new String(b, encoding);
		} catch (Exception e) {
			return null;
		}
	}
	/**      
	 * 生成密钥      
	 */    
	private static void generateKey() throws Exception {        
		/** DES算法要求有一个可信任的随机数源 */        
		SecureRandom sr = new SecureRandom();        
		/** 为DES算法创建一个KeyGenerator对象 */        
		KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM);         
		/** 利用上面的随机数据源初始化这个KeyGenerator对象 */        
		kg.init(sr);        
		/** 生成密匙 */        
		SecretKey key = kg.generateKey();         
		/** 用对象流将生成的密钥写入文件 */        
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(KEYFile));        
		oos.writeObject(key);         
		/** 清空缓存，关闭文件输出流 */        
		oos.close();     
	}       
	/**
	 * 加密方式  
	 * @param source
	 * @return
	 * @throws Exception
	 */
	public static String DESEncrypt(String source) throws Exception {         
		generateKey();         
		/** 
		 * 将文件中的SecretKey对象读出 
		 */        
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(KEYFile));         
		SecretKey key = (SecretKey) ois.readObject();         
		/** 得到Cipher对象来实现对源数据的DES加密 */        
		Cipher cipher = Cipher.getInstance(ALGORITHM);         
		cipher.init(Cipher.ENCRYPT_MODE, key);         
		byte[] b = source.getBytes();         
		/** 执行加密操作 */        
		byte[] b1 = cipher.doFinal(b);         
		BASE64Encoder encoder = new BASE64Encoder();         
		return encoder.encode(b1);     
	}       
	/**      
	 * 解密密钥 cryptograph:密文      
	 */   
	public static String DESDecrypt(String cryptograph) throws Exception {         
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(KEYFile));         
		SecretKey key = (SecretKey) ois.readObject();         
		Cipher cipher = Cipher.getInstance(ALGORITHM);         
		cipher.init(Cipher.DECRYPT_MODE, key);         
		BASE64Decoder decoder = new BASE64Decoder();        
		byte[] b1 = decoder.decodeBuffer(cryptograph);        
		byte[] b = cipher.doFinal(b1);         return new String(b);    
	}  
	/**
	 * SHA1加密 -- old此加密方法有问题,有时候会少一位数,
	 * 但是如果双方使用一致的此加密方法则没问题
	 * 比如:20160324182311STDZ8888888try0987
	 * @param data
	 * @param encoding
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws UnsupportedEncodingException
	 */
	public static String SHAHex(String data,String encoding) {
		MessageDigest md = null;
		try {
			md = MessageDigest.getInstance("SHA-1");
			try {
				md.update(data.getBytes(encoding));
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		byte[] result = md.digest();
		StringBuffer sb = new StringBuffer();

		for (byte b : result) {
			int i = b & 0xff;
			if (i < 0xf) {
				sb.append(0);
			}
			sb.append(Integer.toHexString(i));
		}
		return sb.toString();
	}
	
	/**
	 * SHA1加密 
	 * @param decript
	 * @param encoding
	 * @return
	 */
	public static String SHA1(String decript,String encoding) {
		try {
			MessageDigest digest = MessageDigest
					.getInstance("SHA-1");
			try {
				digest.update(decript.getBytes(encoding));
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			byte messageDigest[] = digest.digest();
			// Create Hex String
			StringBuffer hexString = new StringBuffer();
			// 字节数组转换为 十六进制 数
			for (int i = 0; i < messageDigest.length; i++) {
				String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
				if (shaHex.length() < 2) {
					hexString.append(0);
				}
				hexString.append(shaHex);
			}
			return hexString.toString();

		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return "";
	}
	
	
	/**
	 * java生成随机数字和字母组合
	 * 
	 * @param length
	 *            [生成随机数的长度]
	 * @return
	 */
	public static String getCharAndNumr(int length) {
		String val = "";
		Random random = new Random();
		for (int i = 0; i < length; i++) {
			// 输出字母还是数字
			String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
			// 字符串
			if ("char".equalsIgnoreCase(charOrNum)) {
				// 取得大写字母还是小写字母
				int choice = random.nextInt(2) % 2 == 0 ? 65 : 97;
				val += (char) (choice + random.nextInt(26));
			} else if ("num".equalsIgnoreCase(charOrNum)) { // 数字
				val += String.valueOf(random.nextInt(10));
			}
		}
		return val;
	}

}
